use std::{borrow::Cow, fmt::Display};

use actix_http::StatusCode;

pub trait CodeError {
    fn get_code(&self) -> i64;
    fn get_description(&self) -> Cow<str>;
    #[inline]
    fn get_status_code(&self) -> StatusCode {
        StatusCode::FORBIDDEN
    }
}
#[derive(Debug, Clone, Copy)]
pub struct ConstContentError(&'static str, i64, Option<StatusCode>);

impl ConstContentError {
    pub const fn new(
        content: &'static str,
        code: i64,
        status: Option<StatusCode>,
    ) -> ConstContentError {
        Self(content, code, status)
    }
}
impl CodeError for ConstContentError {
    #[inline]
    fn get_code(&self) -> i64 {
        self.1
    }
    #[inline]
    fn get_description(&self) -> Cow<str> {
        Cow::Borrowed(self.0)
    }
    #[inline]
    fn get_status_code(&self) -> StatusCode {
        match self.2 {
            Some(code) => code,
            None => StatusCode::FORBIDDEN,
        }
    }
}

impl Display for ConstContentError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_fmt(format_args!(
            "code:{}; {}",
            self.get_code(),
            self.get_description()
        ))
    }
}
impl From<ConstContentError> for String {
    fn from(c: ConstContentError) -> Self {
        format!("{}", c)
    }
}
